Imports Clo = Enhancements.Core.Logging
Imports Ere = Enhancements.Basic.RegularExpressions
Imports Exe = Enhancements.Basic.Expressions
Imports Gen = System.Collections.Generic
Imports Glo = System.Globalization
Imports Iou = System.IO
Imports Ref = System.Reflection
Imports Reg = System.Text.RegularExpressions
Imports Sys = System
Imports Tex = System.Text
Imports Xsd = System.Xml.Schema
Imports W3c = System.Xml

Namespace Enhancements.Basic.Expressions.Values
    ''' <summary>Represents a token extracted from an expression that has a value.</summary>
    <Serializable(), DebuggerStepThrough()> _
    Public MustInherit Class Value
        Inherits Exe.Token

        Friend Sub New(ByVal _expression As System.String, ByVal _expressionBeginIndex As Sys.Int32, ByVal _expressionEndIndex As Sys.Int32, ByVal _value As Sys.Object)
            MyBase.New(_expression, _expressionBeginIndex, _expressionEndIndex)
            Value = _value
        End Sub

        Private __Value As System.Object = Nothing
        ''' <summary>The value represented as it's underlying type.</summary>
        ''' <exception cref="IsNullException">_value is null.</exception>
        Public Property Value() As System.Object
            Get
                Return __Value
            End Get
            Private Set(ByVal _value As System.Object)
                Assert.IsNullNot(_value, "Value._value", True)

                __Value = _value
            End Set
        End Property

        Private Shared Function __Parse(ByVal _expression As System.String, ByVal _expressionBeginIndex As Sys.Int32) As Sys.Object
            Dim _returnValue As Sys.Object = Nothing
            Dim _boolean As [Boolean] = Nothing
            Dim _string As [String] = Nothing
            Dim _dateTime As [DateTime] = Nothing
            Dim _number As Number = Nothing
            If [Boolean].TryParse(_expression, _expressionBeginIndex, _boolean) Then
                _returnValue = _boolean
            Else
                If [String].TryParse(_expression, _expressionBeginIndex, _string) Then
                    _returnValue = _string
                Else
                    If DateTime.TryParse(_expression, _expressionBeginIndex, _dateTime) Then
                        _returnValue = _dateTime
                    Else
                        If [Number].TryParse(_expression, _expressionBeginIndex, _number) Then
                            _returnValue = _number
                        End If
                    End If
                End If
            End If
            If Assert.IsNull(_returnValue, "_returnValue", False) Then
                _returnValue = ValueParseException.___Create(_expression, _expressionBeginIndex)
            End If

            Return _returnValue
        End Function

        ''' <summary>Parses an expression for a value starting by a begin index.</summary>
        ''' <param name="_expression">Expression to parse.</param>
        ''' <param name="_expressionBeginIndex">Expression begin index to use.</param>
        ''' <exception cref="ValueParseException">The operation did not produce a valid token.</exception>
        ''' <returns> </returns>
        Public Shared Function Parse(ByVal _expression As System.String, ByVal _expressionBeginIndex As Sys.Int32) As Value
            Dim _returnValue As Sys.Object = __Parse(_expression, _expressionBeginIndex)
            If Assert.IsOfType(_returnValue, "_returnValue", GetType(ValueParseException), False) Then
                ValueParseException.___Throw(CType(_returnValue, ValueParseException))
            End If

            Return CType(_returnValue, Value)
        End Function

        ''' <summary>Tries to parse an expression for a value starting by a begin index.</summary>
        ''' <param name="_expression">Expression to parse.</param>
        ''' <param name="_expressionBeginIndex">Expression begin index to use.</param>
        ''' <param name="_result">The result of the operation if possible. If not, null is returned.</param>
        ''' <returns> </returns>
        Public Shared Function TryParse(ByVal _expression As System.String, ByVal _expressionBeginIndex As Sys.Int32, ByRef _result As Value) As System.Boolean
            Dim _returnValue As System.Boolean = False
            Dim _dummy As Sys.Object = __Parse(_expression, _expressionBeginIndex)
            If Assert.IsOfType(_dummy, "_dummy", GetType(ValueParseException), False) Then
                _result = Nothing
                _returnValue = False
            Else
                _result = CType(_dummy, Value)
                _returnValue = True
            End If

            Return _returnValue
        End Function

        Private Shared __Types() As System.Type = Nothing
        Friend Overloads Shared Function ___TypesGet() As System.Type()
            If __Types.IsNull("__Types", False) Then
                Dim _typesList As Gen.List(Of System.Type) = New Gen.List(Of System.Type)()
                _typesList.Add(GetType([Boolean]))
                _typesList.Add(GetType([String]))
                _typesList.Add(GetType(DateTime))
                _typesList.AddRange(Number.___TypesGet())
                __Types = _typesList.ToArray()
            End If

            Return __Types
        End Function

        Friend Overloads Shared Function ___AssertIsValidValue(ByVal _value As Sys.Object) As System.Boolean
            Dim _returnValue As System.Boolean = [Boolean].___AssertIsValidValue(_value) Or [String].___AssertIsValidValue(_value) Or DateTime.___AssertIsValidValue(_value) Or Number.___AssertIsValidValue(_value)

            Return _returnValue
        End Function

        Friend Overloads Shared Function ___AssertIsValidType(ByVal _type As Sys.Type) As System.Boolean
            Dim _returnValue As System.Boolean = False
            If _type.IsNullNot("_type", False) Then
                If ___TypesGet().Contains(_type) Then
                    _returnValue = True
                End If
            End If

            Return _returnValue
        End Function

        Friend Overloads Shared Function ___AssertIsValidTypeAndValue(ByVal _type As Sys.Type, ByVal _value As Sys.Object) As System.Boolean
            Dim _returnValue As System.Boolean = False
            If ___AssertIsValidType(_type) Then
                If _type Is GetType([Boolean]) AndAlso [Boolean].___AssertIsValidValue(_value) Then
                    _returnValue = True
                Else
                    If _type Is GetType(DateTime) AndAlso DateTime.___AssertIsValidValue(_value) Then
                        _returnValue = True
                    Else
                        If _type Is GetType([String]) AndAlso [String].___AssertIsValidValue(_value) Then
                            _returnValue = True
                        Else
                            If Number.___AssertIsValidTypeAndValue(_type, _value) Then
                                _returnValue = True
                            End If
                        End If
                    End If
                End If
            End If

            Return _returnValue
        End Function

    End Class
End Namespace
